package com.yzr.common.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.HttpMediaTypeNotAcceptableException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

/**
 * @author yx-0173
 * @description 文件下载工具类
 * @date 2020/1/26
 */
@Slf4j
@Component
public class FileDownLoadUtil {

    /**
     * 文件下载
     *
     * @param response    响应
     * @param request     请求
     * @param downloadUrl url
     * @throws Throwable 异常
     */
    public void downLoad(HttpServletResponse response, HttpServletRequest request, String downloadUrl) throws Throwable {
        if (Objects.isNull(downloadUrl)) {
            throw new NullPointerException("下载地址为空");
        }
        File file = new File(downloadUrl);
        if (!file.exists()) {
            log.error("下载文件的地址不存在:{}", file.getPath());
            throw new HttpMediaTypeNotAcceptableException("文件不存在");
        }
        //获取文件名
        String fileName = file.getName();
        // 获取header
        String header = request.getHeader("User-Agent");
        // IE浏览器处理/非IE浏览器的处理
        fileName = header.contains("MSIE") || header.contains("Trident") ? java.net.URLEncoder.encode(fileName, "UTF-8") : new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
        response.reset();
        // ContentType，即告诉客户端所发送的数据属于什么类型
        response.setContentType("application/octet-stream; charset=UTF-8");
        //获得文件的长度
        response.setHeader("Content-Length", String.valueOf(file.length()));
        //设置编码格式
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        ByteStreamUtil.fileCopy(new FileInputStream(file), response.getOutputStream());
    }

    public static ResponseEntity<InputStreamResource> downloadFileResource(final InputStreamResource resource)
            throws UnsupportedEncodingException {
        final HttpHeaders headers = new HttpHeaders();
        final String encodeFileName = URLEncoder
                .encode(Objects.requireNonNull(resource.getFilename()), "UTF-8")
                .replace("+", "%20");
        headers.add(HttpHeaders.CONTENT_DISPOSITION,
                "attachment;filename=" + encodeFileName + ";filename*=UTF-8''" + encodeFileName);

        return ResponseEntity.ok()
                .headers(headers)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(resource);
    }

    private ResponseEntity<InputStreamResource> getResponseEntity(final Path path, final String fileName) throws IOException {
        final InputStreamResource resource = new InputStreamResource(Files.newInputStream(path)) {
            @Override
            public long contentLength() throws IOException {
                return Files.size(path);
            }

            @Override
            public String getFilename() {
                return fileName;
            }
        };
        return downloadFileResource(resource);
    }

}
